// Code file original author: Martin Lapierre, http://devinstinct.com

using System;
using System.Text;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using EntLibContrib.Validation.Validators;
using Microsoft.Practices.EnterpriseLibrary.Validation;
using Microsoft.Practices.EnterpriseLibrary.Validation.Validators;

namespace EntLibContrib.Validation.Tests.Validators
{
    /// <summary>
    /// Tests <see cref="TypeValidator"/>.
    /// </summary>
    [TestClass]
    public class TypeValidatorFixture
    {
        [TestMethod]
        public void ReturnsSuccessForSameType()
        {
            TypeValidator<string> validator = new TypeValidator<string>();
            ValidationResults validationResults = validator.Validate("test");

            Assert.IsTrue(validationResults.IsValid);
        }

        [TestMethod]
        public void NegatedReturnsFailureForSameType()
        {
            TypeValidator<string> validator = new TypeValidator<string>(null, null, true);
            ValidationResults validationResults = validator.Validate("test");

            Assert.IsFalse(validationResults.IsValid);
        }

        [TestMethod]
        public void ReturnsFailureForDifferentTypes()
        {
            TypeValidator<string> validator = new TypeValidator<string>();
            ValidationResults validationResults = validator.Validate(123);

            Assert.IsFalse(validationResults.IsValid);
        }

        [TestMethod]
        public void NegatedReturnsSuccessForDifferentTypes()
        {
            TypeValidator<string> validator = new TypeValidator<string>(null, null, true);
            ValidationResults validationResults = validator.Validate(123);

            Assert.IsTrue(validationResults.IsValid);
        }

        [TestMethod]
        public void ReturnsSuccessForInheritedTypes()
        {
            TypeValidator<TestTargetA> validator = new TypeValidator<TestTargetA>();
            ValidationResults validationResults = validator.Validate(new TestTargetB());

            Assert.IsTrue(validationResults.IsValid);
        }

        [TestMethod]
        public void NegatedReturnsFailureForInheritedTypes()
        {
            TypeValidator<TestTargetA> validator = new TypeValidator<TestTargetA>(null, null, true);
            ValidationResults validationResults = validator.Validate(new TestTargetB());

            Assert.IsFalse(validationResults.IsValid);
        }
        
        [TestMethod]
        public void ReturnsFailureForDerivedTypes()
        {
            TypeValidator<TestTargetB> validator = new TypeValidator<TestTargetB>();
            ValidationResults validationResults = validator.Validate(new TestTargetA());

            Assert.IsFalse(validationResults.IsValid);
        }

        [TestMethod]
        public void NegatedReturnsSuccessForDerivedTypes()
        {
            TypeValidator<TestTargetB> validator = new TypeValidator<TestTargetB>(null, null, true);
            ValidationResults validationResults = validator.Validate(new TestTargetA());

            Assert.IsTrue(validationResults.IsValid);
        }

        [TestMethod]
        public void ReturnsFailureForNull()
        {
            TypeValidator<string> validator = new TypeValidator<string>();
            ValidationResults validationResults = validator.Validate(null);

            Assert.IsFalse(validationResults.IsValid);
        }

        [TestMethod]
        public void NegatedReturnsSuccessForNull()
        {
            TypeValidator<string> validator = new TypeValidator<string>(null, null, true);
            ValidationResults validationResults = validator.Validate(null);

            Assert.IsTrue(validationResults.IsValid);
        }

        [TestMethod]
        public void ReturnsSuccessForZero()
        {
            TypeValidator<int> validator = new TypeValidator<int>();
            ValidationResults validationResults = validator.Validate(0);

            Assert.IsTrue(validationResults.IsValid);
        }

        [TestMethod]
        public void NegatedReturnsFailureForZero()
        {
            TypeValidator<int> validator = new TypeValidator<int>(null, null, true);
            ValidationResults validationResults = validator.Validate(0);

            Assert.IsFalse(validationResults.IsValid);
        }

        /// <summary>
        /// Test target A for this fixture.
        /// </summary>
        public class TestTargetA
        {
        }

        /// <summary>
        /// Test target B for this fixture.
        /// </summary>
        public class TestTargetB
            : TestTargetA
        {
        }
    }
}
